/**
 * SM3 standards:http://www.oscca.gov.cn/News/201012/News_1199.htm
 */
#ifndef HEADER_MD3_H
#define HEADER_MD3_H

#include <openssl/e_os2.h>
#include <openssl/sha.h>
#include <stddef.h>

#ifndef OPENSSL_NO_SM3
/**
 * \brief          SM3 context structure
 */
typedef struct SM3state_st
{
  SHA_LONG total[2]; 	      /*!< number of bytes processed  */
  SHA_LONG state[8];          /*!< intermediate digest state  */
  unsigned char buffer[64];   /*!< data block being processed */
  
  unsigned char ipad[64];     /*!< HMAC: inner padding        */
  unsigned char opad[64];     /*!< HMAC: outer padding        */
  
} SM3_CTX;

#define SM3_DIGEST_LENGTH	32
#define SM3_DIGEST_BITS		256
#define SM3_CBLOCK	(SHA_LBLOCK*4)

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief          SM3 context setup
 *
 * \param ctx      context to be initialized
 */
int SM3_Init (SM3_CTX *ctx);

/**
 * \brief          SM3 process buffer
 *
 * \param ctx      SM3 context
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 */
int SM3_Update (SM3_CTX *ctx, unsigned char *input, size_t ilen);

/**
 * \brief          SM3 final digest
 *
 * \param ctx      SM3 context
 */
int SM3_Final (SM3_CTX *ctx, unsigned char output[32]);

/**
 * \brief          Output = SM3( input buffer )
 *
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 * \param output   SM3 checksum result
 */
void SM3 (unsigned char *input, size_t ilen, unsigned char output[32]);

/**
 * \brief          Output = SM3( file contents )
 *
 * \param path     input file name
 * \param output   SM3 checksum result
 *
 * \return         0 if successful, 1 if fopen failed,
 *                 or 2 if fread failed
 */
int SM3_File (char *path, unsigned char output[32]);

/**
 * \brief          SM3 HMAC context setup
 *
 * \param ctx      HMAC context to be initialized
 * \param key      HMAC secret key
 * \param keylen   length of the HMAC key
 */
void SM3_hmac_init (SM3_CTX *ctx, unsigned char *key, int keylen);

/**
 * \brief          SM3 HMAC process buffer
 *
 * \param ctx      HMAC context
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 */
void SM3_hmac_update (SM3_CTX *ctx, unsigned char *input, size_t ilen);

/**
 * \brief          SM3 HMAC final digest
 *
 * \param ctx      HMAC context
 * \param output   SM3 HMAC checksum result
 */
void SM3_hmac_final (SM3_CTX *ctx, unsigned char output[32]);

/**
 * \brief          Output = HMAC-SM3( hmac key, input buffer )
 *
 * \param key      HMAC secret key
 * \param keylen   length of the HMAC key
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 * \param output   HMAC-SM3 result
 */
void SM3_hmac (unsigned char *key, int keylen,
               unsigned char *input, size_t ilen,
               unsigned char output[32]);


#ifdef __cplusplus
}
#endif

#endif /*OPENSSL_NO_SM3*/

#endif /* sm3.h */
